package com.witdata.common.service.community.impl;

import com.mybatisflex.core.query.QueryWrapper;
import com.witdata.common.domain.Status;
import com.witdata.common.domain.dto.ArticleDto;
import com.witdata.common.domain.vo.*;
import com.witdata.common.exception.GlobalException;
import com.witdata.common.mapper.CommunityMapper;
import com.witdata.common.service.UserService;
import com.witdata.common.service.community.ArticleService;
import com.witdata.common.service.community.CommunityService;
import com.witdata.common.service.system.TagService;
import com.witdata.common.util.IdUtils;
import com.witdata.mysql.base.service.*;
import com.witdata.mysql.domain.entity.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
@RequiredArgsConstructor
public class ArticleServiceImpl implements ArticleService {
    private final CommunityArticleBaseService communityArticleBaseService;
    private final ArticleLikeBaseService articleLikeBaseService;
    private final ArticleCommentBaseService articleCommentBaseService;
    private final TagService tagService;
    private final CommunityService communityService;
    private final UserService userService;
    private final IdUtils idUtils;
    private final ArticleSubCommentBaseService articleSubCommentBaseService;
    private final CommentLikeBaseService commentLikeBaseService;

    @Override
    public List<ArticleDto> getArticleList(Long communityId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("community_id", communityId);
        tagService.getTagListByType("community");
        List<TCommunityArticle> tCommunityArticleList = communityArticleBaseService.list(queryWrapper);
        return CommunityMapper.INSTANCE.toArticleDtoList(tCommunityArticleList);
    }

    @Override
    public List<ArticleVo> getArticleListByTagId(Long communityId, Long tagId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("community_id", communityId);
        queryWrapper.eq("tag_id", tagId);
        List<ArticleVo> articleVoList = new ArrayList<>();
        List<TCommunityArticle> tCommunityArticleList = communityArticleBaseService.list(queryWrapper);
        if (!ObjectUtils.isEmpty(tCommunityArticleList)) {
            tCommunityArticleList.forEach(article -> {
                ArticleVo articleVo = ArticleVo.builder()
                        .id(article.getId())
                        .content(article.getContent())
                        .tag(tagService.getTagById(article.getTagId()))
                        .community(communityService.getCommunityById(article.getCommunityId()))
                        .user(userService.getUserVoById(article.getAuthorId()))
                        .build();
                articleVoList.add(articleVo);
            });
        }
        return articleVoList;
    }

    @Override
    public void publishArticle(ArticleDto articleDto) {
        TCommunityArticle tCommunityArticle = CommunityMapper.INSTANCE.toTCommunityArticle(articleDto);
        tCommunityArticle.setId(IdUtils.createId());
        tCommunityArticle.setUpdated(LocalDateTime.now());
        tCommunityArticle.setCreated(LocalDateTime.now());
        communityArticleBaseService.save(tCommunityArticle);
    }

    @Transactional
    @Override
    public void deleteArticle(Long articleId) {
        Long userId = idUtils.getUserIdByRequest();
        QueryWrapper queryWrapper = new QueryWrapper().eq("id", articleId).eq("author_id", userId);
        if (!communityArticleBaseService.exists(queryWrapper)) {
            throw new GlobalException(Status.DELETEERROR);
        }
        boolean remove = communityArticleBaseService.remove(queryWrapper);
        if (!remove) throw new GlobalException(Status.DELETEERROR);
        articleLikeBaseService.remove(new QueryWrapper().eq("article_id", articleId));
        articleCommentBaseService.remove(new QueryWrapper().eq("article_id", articleId));
        articleSubCommentBaseService.remove(new QueryWrapper().eq("article_id", articleId));
    }

    /**
     * 获取带有点赞和评论数的社区文章列表
     * @return 返回一个ArticleListWithLikeAndCommentCountVo对象的列表，每个对象包含文章的详细信息、点赞数、评论数和当前用户是否点赞的信息
     */
    @Override
    public List<ArticleListWithLikeAndCommentCountVo> getArticleListWithLikeAndCommentCount(Long communityId) {
        // 创建查询条件，筛选出指定社区的所有文章
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("community_id", communityId);
        List<TCommunityArticle> tCommunityArticleList = communityArticleBaseService.list(queryWrapper);
        // 初始化最终返回的文章列表
        List<ArticleListWithLikeAndCommentCountVo> articleVoList = new ArrayList<>();
        // 获取当前请求用户的ID，用于判断文章是否被当前用户点赞
        Long userId = idUtils.getUserIdByRequest();
        // 获取所有文章的点赞记录和评论记录
        List<TArticleLike> articleLikes = articleLikeBaseService.list();
        List<TArticleComment> articleComments = articleCommentBaseService.list();
        List<TArticleSubComment> articleSubComments = articleSubCommentBaseService.list();
        // 使用HashMap统计每篇文章的点赞数、评论数和当前用户是否点赞
        HashMap<Long, Long> articleLikeMap = new HashMap<>();
        HashMap<Long, Long>  articleCommentMap = new HashMap<>();
        HashMap<Long, Boolean> isLikedMap = new HashMap<>();
        // 统计每篇文章的点赞数和当前用户是否点赞
        for (TArticleLike articleLike : articleLikes) {
            articleLikeMap.put(articleLike.getArticleId(), articleLikeMap.getOrDefault(articleLike.getArticleId(), 0L) + 1);
            if(articleLike.getUserId().equals(userId)){
                isLikedMap.put(articleLike.getArticleId(), true);
            }
        }
        // 统计每篇文章的评论数
        for (TArticleComment articleComment : articleComments) {
            articleCommentMap.put(articleComment.getArticleId(), articleCommentMap.getOrDefault(articleComment.getArticleId(), 0L) + 1);
        }
        for (TArticleSubComment articleSubComment : articleSubComments) {
            articleCommentMap.put(articleSubComment.getArticleId(), articleCommentMap.getOrDefault(articleSubComment.getArticleId(), 0L) + 1);
        }
        // 遍历社区文章列表，构建带有点赞数、评论数和当前用户是否点赞信息的文章列表
        for (TCommunityArticle tCommunityArticle : tCommunityArticleList) {
            long likeCount = articleLikeMap.getOrDefault(tCommunityArticle.getId(), 0L);
            long commentCount = articleCommentMap.getOrDefault(tCommunityArticle.getId(), 0L);
            boolean isLiked = isLikedMap.getOrDefault(tCommunityArticle.getId(), false);
            // 构建ArticleListWithLikeAndCommentCountVo对象，并添加到最终返回的文章列表中
            ArticleListWithLikeAndCommentCountVo articleListVo = ArticleListWithLikeAndCommentCountVo.builder()
                    .id(tCommunityArticle.getId())
                    .tagId(tCommunityArticle.getTagId())
                    .communityId(tCommunityArticle.getCommunityId())
                    .content(tCommunityArticle.getContent())
                    .authorId(tCommunityArticle.getAuthorId())
                    .likeCount(likeCount)
                    .commentCount(commentCount)
                    .isLike(isLiked)
                    .build();
            articleVoList.add(articleListVo);
        }
        return articleVoList;
    }

    /**
     * 获取文章详细信息，包括主评论和子评论
     *
     * @param articleId 文章ID
     * @return 返回包含文章信息、评论和子评论的ArticleInfoVo对象
     * @throws GlobalException 如果文章未找到，则抛出全局异常
     */
    @Override
    public ArticleInfoVo getArticleInfo(Long articleId) {
        // 根据文章ID查询文章基本信息
        QueryWrapper wrapper = new QueryWrapper().eq("id", articleId);
        TCommunityArticle article = communityArticleBaseService.getOne(wrapper);
        // 如果文章不存在，抛出异常
        if (article == null) {
            throw new GlobalException(Status.ARTICLENOTFOUND);
        }
        // 查询文章的所有主评论和子评论
        List<TArticleComment> articleComments = articleCommentBaseService.list(new QueryWrapper().eq("article_id", articleId));
        List<TArticleSubComment> articleSubComments = articleSubCommentBaseService.list(new QueryWrapper().eq("article_id", articleId));
        // 查询所有的评论点赞信息
        List<TCommentLike> commentLikes = commentLikeBaseService.list();
        // 获取当前用户ID
        Long userId = idUtils.getUserIdByRequest();
        // 初始化点赞数和是否点赞的映射
        HashMap<Long, Long> likeMap = new HashMap<>();
        HashMap<Long, Boolean> isLikedMap = new HashMap<>();
        // 遍历评论点赞信息，构建点赞数和是否点赞的映射
        for (TCommentLike commentLike : commentLikes) {
            likeMap.put(commentLike.getCommentId(), likeMap.getOrDefault(commentLike.getCommentId(), 0L) + 1);
            if(commentLike.getUserId().equals(userId)){
                isLikedMap.put(commentLike.getCommentId(), true);
            }
        }
        // 将主评论列表转换为ArticleCommentVo列表
        List<ArticleCommentVo> articleCommentVos = articleComments.stream().map(articleComment -> ArticleCommentVo.builder()
                .id(articleComment.getId())
                .articleId(articleComment.getArticleId())
                .userId(articleComment.getUserId())
                .content(articleComment.getContent())
                .likeCount(likeMap.getOrDefault(articleComment.getId(), 0L))
                .isLike(isLikedMap.getOrDefault(articleComment.getId(), false))
                .created(articleComment.getCreated())
                .build()).toList();
        // 将子评论列表转换为ArticleSubCommentVo列表
        List<ArticleSubCommentVo> articleSubCommentVos = articleSubComments.stream().map(articleSubComment -> ArticleSubCommentVo.builder()
                .id(articleSubComment.getId())
                .parentCommentId(articleSubComment.getParentCommentId())
                .articleId(articleSubComment.getArticleId())
                .userId(articleSubComment.getUserId())
                .content(articleSubComment.getContent())
                .likeCount(likeMap.getOrDefault(articleSubComment.getId(), 0L))
                .isLike(isLikedMap.getOrDefault(articleSubComment.getId(), false))
                .created(articleSubComment.getCreated())
                .build()).toList();
        //统计当前文章的点赞数
        List<TArticleLike> articleLikes = articleLikeBaseService.list(new QueryWrapper().eq("article_id", articleId));
        long likeCount = articleLikes.size();
        boolean isLiked = false;
        for (TArticleLike articleLike : articleLikes) {
            if (articleLike.getUserId().equals(userId)) {
                isLiked = true;
                break;
            }
        }
        // 构建并返回ArticleInfoVo对象
        return ArticleInfoVo.builder()
                .id(article.getId())
                .tagId(article.getTagId())
                .communityId(article.getCommunityId())
                .content(article.getContent())
                .likeCount(likeCount)
                .isLike(isLiked)
                .commentCount((long) (articleComments.size()+articleSubComments.size()))
                .authorId(article.getAuthorId())
                .comments(articleCommentVos)
                .secondComments(articleSubCommentVos)
                .build();
    }
}
